home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / UIFlow 1.0.1 / UIFlow Source / Kevin / convert.c next >
Encoding:
C/C++ Source or Header  |  1992-04-23  |  13.9 KB  |  649 lines  |  [TEXT/????]

  1. #pragma segment conv
  2. #define MAC
  3. #include <stdio.h>
  4. #include <vg.h>
  5. #include <vset-prototypes.h>
  6. extern DFR8addimage();
  7. extern DFR8putimage();
  8. extern uint16 DFR8lastref();
  9. extern DFANputlabel();
  10.  
  11. #ifdef MAC
  12. #define malloc NewPtr
  13. #define free(x) DisposePtr((Ptr)(x))
  14. #endif
  15.  
  16. /* dtm stuff. */
  17. int   inport, outport;
  18.  
  19. /* the data struct we use for the data. */
  20. typedef struct {
  21.     int x;
  22.     int y;
  23.     float val;
  24. } datastruct;
  25.  
  26. typedef struct {
  27.     datastruct *p1;
  28.     datastruct *p2;
  29.     datastruct *p3;
  30. }triangle;
  31.  
  32. #include "protypes.h"
  33.  
  34. /* contains the data read from the HDF file. */
  35. int        numNodes;
  36. float * xs, * ys, * vals = (float *) NULL;
  37. float xmax, xmin, ymax, ymin;
  38. float range, max, min;
  39.  
  40. /* connectivity info. */
  41. int rank,numPolys; /* triagles or quads. */
  42. int * con;
  43.  
  44. /* the raster image information. */
  45. int xdim, ydim;
  46. unsigned char * data;
  47.  
  48. /* parameters. */
  49. short dots = 0, debug = 0, dtm = 0, DFR8 = 0;
  50.  
  51. /* access to the current hdf vset file. */
  52. VGROUP    *vg;
  53. VDATA    *vs;
  54. DF        *f;
  55.  
  56. /************************************************************
  57.  
  58.     ReadVSetData (filename)
  59.  
  60.     read the vsets from the HDF file filename.
  61.  
  62. ************************************************************/
  63.  
  64. Boolean ReadVSetData (char * filename)
  65. {
  66.  
  67.     int        nvertices, vsize, interlace;
  68.     char    vsname[50],fields[50];
  69.     int        vsid;
  70.     int        vgid;
  71.  
  72.  
  73.     /* open the HDF file. */
  74.     f = DFopen (filename,DFACC_ALL, 0);
  75.     setjj();
  76.  
  77.     /* read the vgroup. */
  78.     vgid = -1;
  79.     while ((vgid=Vgetid(f, vgid)) != -1)
  80.         {
  81.         xs = ys = NULL;
  82.         con = NULL;
  83.         vg = (VGROUP *) Vattach (f, vgid, "r");
  84.         vsid = -1;
  85.         while ((vsid = Vgetnext(vg, vsid)) != -1)
  86.             {
  87.  
  88.             /* read the x values. */
  89.  
  90.             vs = (VDATA *) VSattach (f, vsid, "r");
  91.             VSinquire (vs, &nvertices, &interlace, fields, &vsize, vsname);
  92.             if (!strncmp (fields, "PX",2))
  93.                 {
  94.                 VSsetfields (vs, "PX");
  95.                 xs = (float *) malloc (nvertices * sizeof(float));
  96.                 if (VSread (vs, (unsigned char*)xs, nvertices, interlace)!=nvertices)
  97.                     return false;
  98.             }
  99.  
  100.             /* now get the y values. */
  101.             if (!strncmp (fields, "PY", 2))
  102.                 {
  103.                 VSsetfields (vs, "PY");
  104.                 numNodes = nvertices;
  105.                 ys = (float *) malloc (nvertices * sizeof(float));
  106.                 if (!ys) return false;
  107.                 if (VSread (vs,(unsigned char*)ys, nvertices, interlace)!=nvertices)
  108.                     return false;
  109.                 }
  110.     
  111.             /* now get the data values. */
  112.             if (!strncmp (fields, "PLIST", 5))
  113.                 {
  114.                 VSsetfields (vs, fields);
  115.                 con = (int *) malloc (vsize * nvertices);
  116.                 if (!con) return false;
  117.                 numPolys = nvertices;
  118.                 rank = vsize/sizeof(int);
  119.                 if (VSread (vs,(unsigned char*)con, nvertices, interlace) != nvertices)
  120.                     return false;
  121.                 }
  122.     
  123.             VSdetach (vs);
  124.             if (con && xs && ys)
  125.                 return true;
  126.     
  127.             }
  128.         
  129.         /* free anything that was allocated. We did not find
  130.         all of the things we need ; xs, ys and con */
  131.         if (xs) free (xs);
  132.         if (ys) free (ys);
  133.         if (con) free (con);
  134.         Vdetach (vg);
  135.         }
  136.         
  137.     return false;
  138. }
  139.  
  140. GetDataMaxMin()
  141. {
  142.     int i;
  143.  
  144.     max = min = vals[0];
  145.  
  146.     for (i = 1; i < numNodes; i++)
  147.         /* find max and min values. */
  148.         if (vals[i] > max) max = vals[i];
  149.         else
  150.             if (vals[i] < min) min = vals[i];
  151.  
  152.     range = max - min;
  153. }
  154.  
  155. GetDimMaxMin()
  156. {
  157.     int i;
  158.  
  159.     xmax = xmin = xs[0];
  160.     ymax = ymin = ys[0];
  161.  
  162.     for (i = 1; i < numNodes; i++)
  163.         {
  164.         /* find the max and min x */
  165.         if (xs[i] > xmax) xmax = xs[i];
  166.         if (xs[i] < xmin) xmin = xs[i];
  167.  
  168.         /* find the max and min y */
  169.         if (ys[i] > ymax) ymax = ys[i];
  170.         if (ys[i] < ymin) ymin = ys[i];
  171.         }
  172.  
  173. }
  174.  
  175. /*********************************************************
  176.  
  177.     CloseVSetFile (filename)
  178.     
  179.     Open the hdf file containing the vset and set access to 
  180.     the first group.
  181.     
  182. ***********************************************************/
  183.  
  184. CloseVSetFile ()
  185. {
  186.     /* detach the vgroup. */
  187.     
  188.     Vdetach (vg);
  189.     
  190.     /* close the HDF file. */
  191.  
  192.     DFclose(f);
  193. }
  194.  
  195.  
  196. /************
  197.  
  198.     FillQuad (....
  199.  
  200.     This routine will fill a quadralateral if lr is not equal to NULL.
  201.     It actuall divides the quad into two triangles, then filles each
  202.     triangle. If lr == NULL it fills only the triangle.
  203.  
  204. **************/
  205.  
  206. FillQuad (tl, tr, ll, lr)
  207.     datastruct *tl, *tr, *ll, *lr;
  208. {
  209.  
  210.     triangle one, two;
  211.  
  212.     /* get the triangle. */
  213.  
  214.     GetTriangles (tl, tr, ll, lr, &one, &two);
  215.  
  216.     FillTriangle (&one);
  217.  
  218.     if (lr != NULL)
  219.         FillTriangle (&two);
  220.  
  221. }
  222.  
  223. /***********
  224.     
  225.     GetTriangles (....
  226.  
  227.     This routine will take the points passed in and make two triangles out
  228.     of them. The triangles are sorted such that the highest verticle point
  229.     is represented first in the data structure.
  230.  
  231. ***********/
  232.  
  233. GetTriangles (tl, tr, ll, lr, one, two)
  234.     datastruct *tl, *tr, *ll, *lr;
  235.     triangle * one, * two;
  236. {
  237.  
  238.     /* lets sort them on the basis of y. */
  239.  
  240.     if (tl->y < tr->y)
  241.         if (tl->y < ll->y) /* tl above tr */
  242.             {
  243.             /* tl above ll, therefore on top. */
  244.             one->p1 = tl;
  245.             if (ll->y < tr->y)
  246.                 {
  247.                 /* ll is just below tl, and tr below ll */
  248.                 one->p2 = ll;
  249.                 one->p3 = tr;
  250.                 }
  251.             else /* tr just below tl, and ll on bottom. */
  252.                 {
  253.                 one->p2 = tr;
  254.                 one->p3 = ll;
  255.                 }
  256.             }
  257.         else /* tl above tr, and tl below ll, therefore ll on top. */
  258.             { 
  259.             one->p1 = ll;
  260.             one->p2 = tl;
  261.             one->p3 = tr;
  262.             }
  263.     else
  264.         if (tr->y < ll->y)
  265.             { /* tr above ll too, so its on top. */
  266.             one->p1 = tr;
  267.             if (ll->y < tl->y)
  268.                 { /* ll above tl so tl on bottom. */
  269.                 one->p2 = ll;
  270.                 one->p3 = tl;
  271.                 }
  272.             else /* ll on bottom. */
  273.                 {
  274.                 one->p2 = tl;
  275.                 one->p3 = ll;
  276.                 }
  277.             }
  278.         else
  279.             { /* ll above tr, tr above tl. */
  280.             one->p1 = ll;
  281.             one->p2 = tr;
  282.             one->p3 = tl;
  283.             }
  284.             
  285.  
  286.  
  287.     /* other triagle. */
  288.     if (lr)
  289.     if (lr->y < tr->y)
  290.         if (lr->y < ll->y) /* lr above tr */
  291.             {
  292.             /* lr above ll, therefore on top. */
  293.             two->p1 = lr;
  294.             if (ll->y < tr->y)
  295.                 {
  296.                 /* ll is just below lr, and tr below ll */
  297.                 two->p2 = ll;
  298.                 two->p3 = tr;
  299.                 }
  300.             else /* tr just below lr, and ll on bottom. */
  301.                 {
  302.                 two->p2 = tr;
  303.                 two->p3 = ll;
  304.                 }
  305.             }
  306.         else /* lr above tr, and lr below ll, therefore ll on top. */
  307.             {
  308.             two->p1 = ll;
  309.             two->p2 = lr;
  310.             two->p3 = tr;
  311.             }
  312.     else /* tr above lr. */
  313.         if (tr->y < ll->y)
  314.             { /* tr above ll too, so its on top. */
  315.             two->p1 = tr;
  316.             if (ll->y < lr->y)
  317.                 { /* ll above lr so lr on bottom. */
  318.                 two->p2 = ll;
  319.                 two->p3 = lr;
  320.                 }
  321.             else /* ll on bottom. */
  322.                 {
  323.                 two->p2 = lr;
  324.                 two->p3 = ll;
  325.                 }
  326.             }
  327.         else
  328.             {
  329.             two->p1 = ll;
  330.             two->p2 = tr;
  331.             two->p3 = lr;
  332.             }
  333.         
  334.  
  335. }
  336.     
  337. /**************************************************************************
  338.  
  339.     This routine does the actual gouraud shading of a triangle.
  340.     It works like this: for each verticle raster scan line, we
  341.     need to determin which edges of the triangle are intersected.
  342.     With this done, it is a simple matter of bi-directional interpolation.
  343.     first we compute the values (pixel values) on each of the edges 
  344.     where the horizontal raster scan line or ray intersects. Then we 
  345.     do linear interpolation of the values along the line until we reach
  346.     the other edge.
  347.  
  348. ****************************************************************************/
  349.  
  350. FillTriangle (tri)
  351.     triangle * tri;
  352. {
  353.     float slope1, yint1; /* params for equation of line 1. */
  354.     int dy1, dy2, dx1, dx2;
  355.     float slope2, yint2; /* params for equation of line 1. */
  356.     int xleft, xright;
  357.     int counter,loc;
  358.     float boundstart1, boundstart2, valueinc1,valueinc2;
  359.     
  360.     /* bres equation for line 1. */
  361.     dy1 = (tri->p2->y - tri->p1->y);
  362.     if ((dx1 = tri->p2->x - tri->p1->x))
  363.         slope1 = ((float)dy1) / (float)dx1;
  364.     yint1 = (float)tri->p1->y - slope1*(float)tri->p1->x;
  365.  
  366.     /* equation for line two */
  367.     dy2 = (tri->p3->y - tri->p1->y);
  368.     if ((dx2 = tri->p3->x - tri->p1->x))
  369.         slope2 = ((float) dy2) / (float) dx2;
  370.     yint2 = (float)tri->p1->y - slope2*(float)tri->p1->x;
  371.  
  372.     /* do the top segment->
  373.             .
  374.                       .  . top segment
  375.                     .     .
  376.                    --------------------------------
  377.                       .     . bottom segment
  378.                         .    .
  379.                           .   .
  380.                             .  .
  381.                               . .
  382.                                 ..
  383.                                   .
  384.     */
  385.  
  386.     /* shade the bugger top down. loc is the current raster scan line at
  387.         off set loc. */
  388.  
  389.     /* compute the number of scan line to be generated for this segment. */
  390.  
  391.     counter = dy1;
  392.  
  393.     xright = xleft = tri->p1->x;
  394.     boundstart1 = boundstart2 = tri->p1->val;
  395.     if (dy1)
  396.         valueinc1 = ((float)(tri->p2->val - tri->p1->val))/((float)dy1);
  397.     else valueinc1 = 1.0;
  398.  
  399.     if (dy2)
  400.         valueinc2 = ((float)(tri->p3->val - tri->p1->val))/((float)dy2);
  401.     else valueinc2 = 1.0;
  402.  
  403.     for (loc = tri->p1->y; loc <= tri->p2->y; loc++)
  404.         {
  405.  
  406.         if (dx1)
  407.             if (slope1 != 0.0)
  408.                 xleft = (short) (((float)loc - yint1)/slope1);
  409.  
  410.         if (dx2)
  411.             if (slope2 != 0.0)
  412.                 xright =(short) (((float) loc - yint2)/slope2);
  413.  
  414.         if (xleft == xright)
  415.             SmoothColorLine (data + (loc*xdim) + xright, 1, boundstart2, 0);
  416.         else
  417.             if (xleft > xright)
  418.                 SmoothColorLine (data + (loc*xdim) + xright,
  419.                     xleft - xright + 1, boundstart2,
  420.                     (boundstart1 - boundstart2)/(float)(xleft-xright));
  421.             else
  422.                 SmoothColorLine (data + (loc*xdim) + xleft,
  423.                     xright - xleft + 1, boundstart1,
  424.                     (boundstart2 - boundstart1)/(float)(xright-xleft));
  425.  
  426.         boundstart1 += valueinc1;
  427.         boundstart2 += valueinc2;
  428.         }
  429.  
  430.     /* bres equation for line 1. */
  431.     dy1 = (tri->p3->y - tri->p2->y);
  432.     if (dx1 = tri->p3->x - tri->p2->x)
  433.         slope1 = ((float)dy1) / (float)dx1;
  434.     yint1 = (float)tri->p3->y - slope1*(float)tri->p3->x;
  435.  
  436.     /* compute the number of scan line to be generated for this segment. */
  437.  
  438.     counter = dy1;
  439.  
  440.     xleft = tri->p2->x;
  441.     boundstart1 =  tri->p2->val;
  442.     if (dy1)
  443.         valueinc1 = ((float)(tri->p3->val - tri->p2->val))/((float)dy1);
  444.     else
  445.         valueinc1 = 1.0;
  446.  
  447.     boundstart1 += valueinc1;
  448.     for (loc = tri->p2->y+1; loc <= counter+tri->p2->y; loc++)
  449.         {
  450.  
  451.         if (dx1)
  452.             if (slope1 != 0.0)
  453.                 xleft = (short) (((float)loc - yint1)/slope1);
  454.  
  455.         if (dx2)
  456.             if (slope2 != 0.0)
  457.                 xright =(short) (((float) loc - yint2)/slope2);
  458.  
  459.         if (xleft == xright)
  460.             SmoothColorLine (data + (loc*xdim) + xright, 1, boundstart2, 0);
  461.         else
  462.             if (xleft > xright)
  463.                 SmoothColorLine (data + (loc*xdim) + xright,
  464.                     xleft - xright+1, boundstart2,
  465.                     (boundstart1 - boundstart2)/(float)(xleft-xright));
  466.             else
  467.                 SmoothColorLine (data + (loc*xdim) + xleft,
  468.                     xright - xleft+1, boundstart1,
  469.                     (boundstart2 - boundstart1)/(float)(xright-xleft));
  470.  
  471.         boundstart1 += valueinc1;
  472.         boundstart2 += valueinc2;
  473.         }
  474.  
  475. }
  476.  
  477. DrawDots (pt)
  478.     datastruct * pt;
  479. {
  480.     *(data + (pt->y * xdim) + pt->x) = 255;
  481. }
  482.  
  483. Boolean SmoothColorLine (where, howmany, startval, inc)
  484.     register char * where;
  485.     register int howmany;
  486.     register float startval, inc;
  487. {
  488.     register float value;
  489.  
  490. if (range == 0.0)
  491.     {
  492.     return false;
  493.     }
  494.  
  495.     for (;howmany; howmany--,where++,startval+=inc)
  496.         {
  497.         value =  ((startval - min)/range) * 253.0 + 1.0;
  498.         *where = (char) value;
  499.         }
  500. }
  501.  
  502. /*
  503.  *    This is the routine that is called in order to conver the vset data to raster
  504.  *    images. The vset data is read from the file vset.out writen by prataps fortran
  505.  *     code.
  506.  */
  507.  
  508. int ConvertVSet2Raster(char    * dfFileName)
  509. {
  510.     datastruct tl, tr, ll, lr;     /* contain vertices for the quads. */
  511.     int     i; 
  512.     unsigned char * dptr;
  513.     float     xscale;
  514.     int        *current;
  515.     Boolean firstPut = true;
  516.     int        nvertices, vsize, interlace;
  517.     char    vsname[50],fields[50];
  518.     int        vsid;
  519.     int     xsize = 0;
  520.     uint16     ref;
  521.     char     fName[512];
  522.     int        len;
  523.     
  524.     len = strlen(dfFileName);
  525.     if (len > 512)
  526.         return -1;
  527.         
  528.     strcpy(fName,dfFileName);
  529.  
  530.     /* the purpose of this program is to demonstrate the 
  531.     interpolated fill of a rectangle. */
  532.     
  533.     if (!ReadVSetData("vset.out"))
  534.         return -2;
  535.         
  536.     if (!xs || !ys || !con)
  537.         return -1;
  538.  
  539.     GetDimMaxMin();
  540.     if (xsize == 0)
  541.         xsize = 200;
  542.     xdim = xsize;
  543.     ydim = (int) ((ymax-ymin)/(xmax-xmin) * (float)xsize);
  544.     ydim++;
  545.     
  546.     /* try to allocate memory. */
  547.     data = (unsigned char *) malloc (xdim*ydim);
  548.     if (!data)
  549.         return -1;
  550.     xscale = ((float)xdim)/(xmax - xmin);    /* compute the scale */
  551.  
  552.     /* now get the data values. */
  553.     vsid = -1;
  554.     while ((vsid = Vgetnext(vg, vsid)) != -1)
  555.         {
  556.  
  557.         /* read the x values. */
  558.         vs = (VDATA *) VSattach (f, vsid, "r");
  559.         VSinquire (vs, &nvertices, &interlace, fields, &vsize, vsname);
  560.         if (!strncmp (fields, "PX",2))
  561.             continue;
  562.             
  563.         if (!strncmp (fields, "PY",2))
  564.             continue;
  565.             
  566.         if (!strncmp (fields, "PLIST",5))
  567.             continue;
  568.             
  569.         /* init the raster image to some background color. */
  570.         for (dptr = data, i = 0 ; i < xdim*ydim; i++,dptr++)
  571.             *dptr = 0;
  572.             
  573.         VSsetfields (vs, fields);
  574.         if (vals == NULL)
  575.             vals = (float *) malloc (nvertices * sizeof(float));
  576.             
  577.         if(VSread (vs,(unsigned char*)vals, nvertices, interlace)!=nvertices)
  578.             {
  579.             free (data); 
  580.             free (xs); 
  581.             free (ys); 
  582.             free (con);
  583.             return -1;
  584.             }
  585.     
  586.         /* shade the quadralaterals */
  587.     
  588.         GetDataMaxMin();
  589.         for (i = 0; i < numPolys; i++)
  590.             {
  591.             /* set up the tl. */
  592.     
  593.             current = con + (i * rank);
  594.     
  595.             tl.x = (xmax - xs[current[0]-1]) * xscale;
  596.             tl.y = (ymax - ys[current[0]-1]) * xscale;
  597.             tl.val = vals[current[0]-1];
  598.     
  599.             tr.x = (xmax - xs[current[1]-1]) * xscale;
  600.             tr.y = (ymax - ys[current[1]-1]) * xscale;
  601.             tr.val = vals[current[1]-1];
  602.     
  603.             lr.x = (xmax - xs[current[2]-1]) * xscale;
  604.             lr.y = (ymax - ys[current[2]-1]) * xscale;
  605.             lr.val = vals[current[2]-1];
  606.     
  607.             if (rank == 4)
  608.                 {
  609.                 if (current[3] != 0)
  610.                     {
  611.                     ll.x = (xmax - xs[current[3]-1]) * xscale;
  612.                     ll.y = (ymax - ys[current[3]-1]) * xscale;
  613.                     ll.val = vals[current[3]-1];
  614.                     FillQuad (&tl, &tr, &ll, &lr);
  615.                     }
  616.                 else
  617.                     FillQuad (&tl, &tr, &lr, NULL);
  618.     
  619.                 }
  620.             else
  621.                 FillQuad (&tl, &tr, &lr, NULL);
  622.         
  623.             }
  624.             
  625.         /* do the hdf stuff. */
  626.         
  627.         if (firstPut)
  628.             {
  629.             DFR8putimage (fName, data, xdim, ydim, NULL);
  630.             firstPut = false;
  631.             }
  632.         else
  633.             DFR8addimage (fName, data, xdim, ydim, NULL);
  634.             
  635.         /* add a label for the image. */
  636.         ref = DFR8lastref ();
  637.         DFANputlabel (fName, (uint16) DFTAG_RIG, ref, vsname);
  638.         
  639.     }
  640.     CloseVSetFile();
  641.     free (data); 
  642.     free (xs); 
  643.     free (ys); 
  644.     free (con);
  645.     
  646.     return 0;
  647. }
  648.  
  649.